/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
var JooS = {
 Reflect: (function(F) {
  return function(source, methods) {
   if (!methods)
    methods = { };
   if (source) {
    if (!source.prototype.__constructor)
     source.prototype.__constructor = source;
    F.prototype = source.prototype;
   }
   else
    F.prototype = { constructor: source = F };

   var c;
   if (methods.__constructor) {
    F.prototype = new F;
    c = this.Virtual(F, { __constructor: methods.__constructor }).prototype.__constructor;
    c.prototype = new F;
    delete methods.__constructor;
   }
   else {
    c = function() {
     if (this.__constructor)
      this.__constructor.apply(this, arguments);
    };
    c.prototype = new F;
   }
   c.constructor = source;

   return c.prototype.constructor = this.Virtual(c, methods);
  }
 })(new Function),

 Virtual: (function(hidden) {
  var __index = 1;

  var __extend = function(constructor, name, __self) {
   var __parent = constructor.prototype[name], method;
   if (typeof __self == "function") {
    var __selfName = __self.__name = name + "::" + __index++;
    constructor.prototype[__selfName] = __self;

    if (__parent && typeof __parent == "function") {
     var __thisObj, __originalParent = __self.__parent = __parent.__self || __parent;

     method = function(a1, a2, a3) {
      __thisObj = this;
      __parent = __originalParent;

      switch (arguments.length) { // I'm cheater. Almost...
       case 0: return this[__selfName]();
       case 1: return this[__selfName](a1);
       case 2: return this[__selfName](a1, a2);
       case 3: return this[__selfName](a1, a2, a3);
       default: return __self.apply(this, arguments);
      }
     };

     method.__parent = function(a1, a2, a3) {
      var o = __parent, r;

      __parent = o.__parent;
      switch (arguments.length) {
       case 0: r = __thisObj[o.__name](); break;
       case 1: r = __thisObj[o.__name](a1); break;
       case 2: r = __thisObj[o.__name](a1, a2); break;
       case 3: r = __thisObj[o.__name](a1, a2, a3); break;
       default: r = o.apply(__thisObj, arguments);
      }
      __parent = o;

      return r;
     };

     method.__self = __self;
    }
   }

   constructor.prototype[name] = method || __self;
  };

  for (var IE = "IE" in { toString: IE })
   hidden = false;

  return function(constructor, methods) {
   for (var name in methods)
    __extend(constructor, name, methods[name]);

   if (hidden) // thanks to Andrea Giammarchi
    for (var i=0; i<hidden.length, name = hidden[i]; i++)
     if(methods.hasOwnProperty(name))
      __extend(constructor, name, methods[name]);

   return constructor;
  };
 })([ "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf" ]),

 Mixin: function(destination, source) {
  for (var i in source.prototype)
   if (!destination.prototype[i] && i != "constructor")
    destination.prototype[i] = source.prototype[i];
 },
 Clone: (function(F) {
  return function(Obj) {
   F.prototype = Obj || { };
   return new F();
  };
 })(new Function),

 Extend: function(destination, source) {
  for (var i in source)
   destination[i] = source[i];
  return destination;
 }
};